Eine Subroutine ist ein Unterprogramm (eine Prozedur), das mehrere zusammengehörende Anweisungen ausführt, ohne einen bestimmten Wert zurückzugeben. Eine vordefinierte Subroutine ist zum Beispiel die folgende Methode der Objekthierarchie von MS Excel:
Worksheets(“XY”).Columns(“A:C”).Calculate
Die vordefinierte Subroutine Calculate berechnet alle Formeln des Zellbereichs A:C des Tabellenblatts XY neu. Die folgende Subroutine ist hingegen benutzerdefiniert. zeigeBereichRot() zeigt den mit XY benannten Zellbereich rot an:
Sub zeigeBereichRot() Range(“XY").Select Selection.Font.ColorIndex = 3 ‘Farbindex = 3 (rot) End Sub
Eine Funktion gibt im Gegensatz zur Subroutine einen Wert eines bestimmten Datentyps zurück. Die vordefinierte Tabellenblatt-Funktion SUMME(3;2) ergibt zum Beispiel den numerischen Wert 5. Eine Funktion kann deshalb in einer Formel (insbesondere einer Tabellenformel) vorkommen. Das Ergebnis der folgenden Formel ist zum Beispiel 10:
SUMME(3;2) + 5.
Wir haben im Beispiel QuadratDialog Anweisungen (insbesondere Steueranweisungen), Unterprogramme (Subroutinen und Funktionen), Datentypen und Objekte eingeführt. Die nächsten Abschnitte veranschaulichen diese Begriffe am Programm Wort.xls. Es löscht Wort für Wort einer Textzeile, bis sie leer ist. Das folgende Bild veranschaulicht den Programmablauf am Beispiel der Textzeile Oh Klotilde, Du allein sollst und musst die Meine sein:
Wort.xls. gibt den Text auf dem Tabellenblatt Ausgabeblatt aus. Jede Zelle des Tabellenblatts beginnt auf dem Schnittpunkt einer Zeile und einer Spalte. Sie lässt sich deshalb mit der Eigenschaft Cells(Zeile, Spalte) eindeutig adressieren. Die Zeilen eines Tabellenblatts sind von oben bis unten nummeriert. Analog werden die Spalten von links nach rechts gezählt. Die erste Zeile des Texts steht deshalb in der Zelle (2, 2), die nächste in (3, 2) und die letzte in (11, 2).Das Hilfethema Modularisierung zeigt, dass ein Problem nach dem Grundsatz Divide et impera in Teilprobleme (Module) zerlegt werden kann. Wir gehen auch in Wort.xls so vor. Der folgende Programmausschnitt zeigt die Hauptprozedur WortFürWortLöschen(). Im Initialisierungsteil weist sie zuerst den Text Oh Klotilde ... der Zelle am Schnittpunkt zwischen der zweiten Spalte und der zweiten Zeile des Ausgabeblatts zu. Dann löscht sie in einer Schleife solange das erste Wort der jeweiligen Zeile, bis der Text leer ist.
Sub WortFürWortLöschen() Dim Zeile As Integer, Text As String ‘ —- Initialisierung Zeile = 2 Text = “Oh Klotilde, Du allein sollst und musst ...” ‘ —- Zeile 2 Ausgabeblatt.Cells(Zeile, 2) = Text Do While einWortWeniger(Text) Zeile = Zeile + 1 ‘ —- Zeile 3 etc. Ausgabeblatt.Cells(Zeile, 2) = Text Loop End Sub
Das Löschen eines Worts und die Prüfung auf das Ende der Schleife delegiert die Subroutine an die Funktion einWortWeniger(Text):
Do While einWortWeniger(Text) Zeile = Zeile + 1. Ausgabeblatt.Cells(Zeile, 2) = Text Loop
Ausführungsbedingung der While-Schleife ist die Funktion einWortWeniger(Text). Die Bedingung trifft solange zu, wie es möglich ist, auf jeder neuen Zeile ein Wort weniger anzuzeigen. Weil eine Bedingung immer wahr oder falsch ist, muss die Funktion den Wert True oder False ergeben. Die Funktion ist deshalb vom Datentyp Boolean (siehe Datentypen). Die Schleife erhöht in jedem Durchlauf die Nummer der jeweiligen Zelle und weist ihr den in der Funktion einWortWeniger(Text) gekürzten Text zu.
Der Aufruf von einWortWeniger(Text) übergibt das Argument Text. Das Hilfethema Argumente handelt nur von Argumenten, die vom aufgerufenen Unterprogramm nicht geändert werden. Text ist hingegen ein Eingabe- und Ausgabeargument. Es wird von der Funktion einWortWeniger(Text) modifiziert - nämlich ein Wort kürzer - zurückgegeben. Wir werden dieses Problem später vertiefen.
Die Subroutine WortFürWortLöschen() verwendet zwei Arten von Funktionen:
Cells(Zeile, Spalte) ist eine vordefinierte Funktion und gibt den Wert eines Objekts der Klasse Cell mit der Adresse (Zeile, Spalte) zurück.
einWortWeniger(Text) ist eine benutzerdefinierte Funktion, die solange zutrifft, wie ein erstes Wort von Text gelöscht werden kann. einWortWeniger(Text) ruft ihrerseits die folgenden vordefinierten Funktionen auf:
|
Funktionsname und -argumente |
Rückgabewert |
|
InStr(Text, String) |
Position von String in Text |
|
Right(Text, N) |
N rechte Zeichen von Text |
|
Len(Text) |
Zeichenzahl (engl. length) von Text |
Die Definition von einWortWeniger folgt der allgemeinen Funktionssyntax:
Function <Name> ( <Argumente> ) As <Rückgabetyp>
<Vereinbarungsanweisungen>
<ausführbare Anweisungen>
End FunctionFunction einWortWeniger(Text As String) As Boolean Dim PosLeer As Integer PosLeer = InStr(Text, “ ”) If PosLeer <> 0 Then Text = Right(Text, Len(Text) - PosLeer) einWortWeniger = True Else einWortWeniger = False End If End Function
Weil einWortWeniger(Text) den Text ohne das erste Wort zurückgeben soll, sucht es zuerst die Position der ersten Leerstelle des Texts (PosLeer). Falls eine Leerstelle existiert, weist die Funktion dem Argument Text den bisherigen Text ohne die Zeichen bis und mit der ersten Leerstelle zu. einWortWeniger wird False, falls keine Leerstelle mehr existiert, die den Text in einen linken und rechten Teil trennt.
Jeder Aufruf von einWortWeniger(Text) ergibt nicht nur einen Rückgabewert True oder False, sondern ändert auch das Argument Text (Oh Klotilde ...). Eine aufrufende Prozedur kann der aufgerufenen Prozedur ein Argument als Adresse oder als Kopie übergeben:
Das übergebene Argument steht im Speicher des aufrufenden Programms. Wenn das aufgerufende Programm dieses Argument ändert, modifiziert es also einen Speicherplatz des aufrufenden Programms. Die Funktion einWortWeniger(Text) ändert zum Beispiel direkt den Text der Subroutine WortFürWortLöschen(), das heisst jeder Aufruf löscht unwiderruflich ein Wort des Originaltexts. Die Ausgabe von WortFürWortLöschen() sieht deshalb wie folgt aus:
Oh Klotilde, Du allein sollst und musst die Meine sein
Oh Klotilde, Du allein sollst und musst die Meine
Oh Klotilde, Du allein sollst und musst die
...
Das aufgerufende Programm manipuliert nur die Kopie eines Speicherplatzes des aurufenden Programms. Die Funktion einWortWeniger(Text) ändert zum Beispiel nur eine Kopie des Texts der Subroutine WortFürWortLöschen(). Die ursprüngliche Variable Text bleibt erhalten. Die Ausgabe von WortFürWortLöschen() wäre deshalb ...
Oh Klotilde, Du allein sollst und musst die Meine sein
Oh Klotilde, Du allein sollst und musst die Meine sein
...
Die Übergabe einer Adresse (call by reference) sollte nur dann gewählt werden, wenn der Entwickler sicher ist, dass die übergebene Variable des aufrufenden Programms geändert werden darf. Call by reference ist allerdings effizienter, weil keine Kopie erstellt werden muss. Es ist deshalb in den meisten Programmiersprachen die Voreinstellung. Wenn ein Argument als Kopie übergeben werden soll, muss es in der Vereinbarung des empfangenden Unterprogramms mit ByVal eingeleitet werden. Die folgende Abbildung veranschaulicht die Übergabe eines Arguments grafisch:

Die folgende Tabelle bewertet
die beiden Aufrufarten zusammenfassend:
|
By Reference |
By Value |
|
| Syntax | (Voreinstellung) | ByVal |
| Übergabe | Adresse | Kopie |
| Speichereffizienz | + | - |
| Laufzeiteffizienz | + | - |
| Sicherheit | - (Aufrufumgebung beeinflusst) | + (Aufrufumgebung bleibt unbeeinflusst) |